# Процессинг Лояльности на 1С o_O

## История

Давным-давно, когда 1С был основным моим языком программирования, встала передо мной задача разработки сервиса для расчета лояльности по заказам в сети продуктовых магазинов. Этот сервис в нашей компании назвали Процессингом Лояльности.

В те времена 1С умел публиковаться только как SOAP-сервис. Однако, это не было основной проблемой на моем самурайском пути.

## JSON-сериализация

Все началось с JSON... Нашел я несколько вариантов готовых решений по сериализации / десериализации JSON, прогнал бенчмарки, сравнил результаты. И да, в то время не было платформенных методов работы с JSON. И да, парсинг проводился чуть ли не по символьным чтением строки. Но, не смотря на это мне удалось выбрать оптимальный вариант сериализации.

## База данных

Следующий шаг - работа с базой данных MS SQL. "Внешние источники данных", - подумал я. За пару дней накидал структуру, накодил расчет каких-то простеньких акций и все готово к презентации!

Закинул тестовый пул из 100 заказов и самописный бенч выдал мне среднее время расчета в 20 секунд... Повисла неловкая тишина... И в этот момент я понял что внешние источники данных не вписываются в систему с требованиями по высокой скорости обработки запросов.

Все тот же шаг - работа с базой. Но теперь я взял [ADO-библиотеку](https://www.script-coding.com/ADO.html) для поднятия подключения из 1С к базе данных. Переписал всё с внешних источников данных на запросы MS SQL, слегка поработал с планами запросов и подкорректировал индексы. И среднее время расчета упало до миллисекунд.

В дальнейшем конечно же в сервисе прибавилось разных видов акций, плюс множество дополнительных функций (например, формирование персональных предложений "на лету", отправка PUSH-уведомлений в мобильное приложение и прочее). Все время нужно было следить за планами запросов, и пытаться сокращать количество запросов к базе данных, чтобы не выходить за рамки критического времени обработки запросов, которое я сам себе установил - 1 секунда (в лучших традициях системы 1С).

## Продакшен

Настало время запуска в продакшен. Воздвиг на жирнющий сервер платформу 1С, поставил Apache и опубликовал свою базу. По началу все было неплохо, пока не начались непонятные проблемы с зависающими сеансами и соединениями. Лечилось это только перезапуском службы 1С, что плохо сказывалось на доступности сервиса. Плюс обновление сервиса возможно было ночью с 23:00 до 08:00, а на старте обновлять приходилось часто.

На помощь пришел NGINX. Подняли мы кучку небольших виртуальных серверов (на каждом одинаковая конфигурация Процессинга Лояльности), настроили балансировщик и получился вполне неплохой вариант.

## Развитие и эксплуатация

В процессе развития сервиса перешел на новую версию платформы, с SOAP на HTTP, а так же на сериализацию JSON средствами платформы 1С. Но все это не лишило основных недостатков использования этой технологии для реализации высоконагруженных систем:

1. Сборщик мусора конечно есть, но в 1С где то затаился косяк. И когда работаешь со структурами высокой вложенности могут появиться утечки памяти.

```
Для каждого ТекущаяСтрока Из МассивСтруктур Цикл
	...
КонецЦикла;
```

Решается очисткой всех переменных в процедурах и функциях:

```
ТекущаяСтрока = Неопределено;
```

А так же рекурсивной чисткой всех объектов (структур, массивов структур, таблиц со ссылками на структуры и прочее):

```
Процедура УничтожитьОбъект(ИсходныйОбъект) Экспорт

	Если ТипЗнч(ИсходныйОбъект) = Тип("Массив") Тогда
		Для каждого ТекущаяСтрока Из ИсходныйОбъект Цикл
			УничтожитьОбъект(ТекущаяСтрока);
		КонецЦикла;
		ИсходныйОбъект = Неопределено;

	ИначеЕсли ТипЗнч(ИсходныйОбъект) = Тип("Структура") Тогда
		Для каждого ТекущаяСтрока Из ИсходныйОбъект Цикл
			УничтожитьОбъект(ИсходныйОбъект[ТекущаяСтрока.Ключ]);
		КонецЦикла;
		ИсходныйОбъект = Неопределено;

	ИначеЕсли ТипЗнч(ИсходныйОбъект) = Тип("ТаблицаЗначений") Тогда
		ИсходныйОбъект.Очистить();
		ИсходныйОбъект = Неопределено;
	КонецЕсли;

КонецПроцедуры
```

Ну и конечно нужно закрывать все открытые соединения и чистить переменные с COM-объектами.

2. Нет возможности использования одного соединения к базе данных на несколько запросов. Для каждого запроса приходится понимать свое соединение, а в конце обработки убивать его.

3. Нет возможности кеширования данных в рантайме, без использования внешних сервисов. Абсолютно все данные для обработки приходится получать заново для каждого запроса.

4. Периодически все же возникают ошибки, связанные с сеансами. Поэтому время от времени для профилактики выполняю перезапуск служб 1С на всех серверах процессинга.

Сейчас конечно процессинг уже достиг зрелости и работает вполне стабильно. Все операции обложены метриками, а исключения логируются. Так что в любой момент времени у меня есть оперативные данные о скорости работы сервиса, а за ошибками и метриками следит специальный сервис мониторинга.

## Что дальше?

Разработка Процессинга стартовала в начале 2016 года. И с тех пор я выпустил семь версий. Некоторые версии несли в себе серьезные изменения внутренней архитектуры сервиса, а некоторые версии стали переходными для поддержки обратной совместимости кассового софта (таких было три версии). Кстати, одна из них, 3-я версия, работает до сих пор только ради одного ресторана.

Сейчас, в 2021-м, я планирую последнюю для процессинга на 1С мажорную 8-ю версию (опять же в лучших традициях 1С) с модернизированной системой управления акциями, что по сути затрагивает самое ядро сервиса.
Далее от процессинга я буду "откусывать" кусочки функционала и оформлять их в виде микросервисов на Go. А в коде самого процессинга заменять вызов внутренних функций на отправку запросов нужным сервисам. В итоге я должен получить обновленный процессинг в микросервисной архитектуре, готовый к расширению функционала и дальнейшему развитию.

## Итоги

Подводя итоги, благодаря 1С мы смогли реализовать проект высоконагруженного сервиса с высоким показателем скорости обработки запросов и доступности, а я вполне успевал реализовывать достаточно сложный функционал в сжатые сроки. Так что, даже если в штате компании из программистов трудятся только специалисты 1С - это не помеха для реализации подобных проектов.
